const path = require('path');
const fs = require('fs');
const moment = require("moment");
const config = require("../db/config");

const TAG = "[目录工具]";
let directoryUtils = {
    // 确保目录存在的函数
    ensureDirectory: function (directory) {
        const logDirectory = path.dirname(directory);

        if (!fs.existsSync(logDirectory)) {
            fs.mkdirSync(logDirectory, {recursive: true});
        }
    },
    // 输入一个多级的目录 ，分级判断是否存在，不存在则创建
    ensureDirectoryByPath: function (directory) {
        let arr = directory.split('/');
        let merge = '';
        for (let i = 0; i < arr.length; i++) {
            if (!arr[i]) {
                merge = '/';
            } else {
                merge = merge + arr[i] + '/';
            }
            if (merge !== '/') {
                if (!fs.existsSync(merge)) {
                    // console.info("创建路径");
                    fs.mkdirSync(merge);
                }
            }
        }
    },
    // 在指定文件夹里找到日期最后一个文件，把它的名称修改，加上 "-YYYYHHmm_hh:mm:ss" ， 即加上当前的时间。
    // 如果没有找到文件，则返回空字符串
    renameLastFile: function (directory) {
        let files = fs.readdirSync(directory);
        let lastFile = '';
        let lastTime = 0;
        for (let i = 0; i < files.length; i++) {
            let stat = fs.statSync(directory + '/' + files[i]);
            if (stat.isFile() && files[i].indexOf("_") < 0) {
                if (stat.mtimeMs > lastTime) {
                    lastTime = stat.mtimeMs;
                    lastFile = files[i];
                }
            }
        }
        if (lastFile) {
            let now = moment();
            const nowStr = now.format('YYYYMMDD-HHmmss');
            let newFile = lastFile.replace(".mkv", `_${nowStr}.mkv`);
            fs.renameSync(directory + '/' + lastFile, directory + '/' + newFile);
            return newFile;
        } else {
            return '';
        }
    },
    // 递归遍历目录下所有层级文件并计算总空间
    calculateTotalSpace: function (directory) {
        let size = 0;

        try {
            // 获取目录下所有文件和子目录
            const files = fs.readdirSync(directory);

            // 遍历文件和子目录
            for (let i = 0; i < files.length; i++) {
                const filePath = path.join(directory, files[i]);

                // 获取文件信息
                const stat = fs.statSync(filePath);

                if (stat.isFile()) {
                    // 如果是文件，累加文件大小
                    size += stat.size;
                } else if (stat.isDirectory()) {
                    // 如果是子目录，递归调用 calculateTotalSpace
                    size += this.calculateTotalSpace(filePath);
                }
            }

        } catch (e) {
            //console.info(TAG, "可能没有权限", directory, e);
        }

        // 返回总空间
        return size;
    },

    // 递归遍历目录下所有层级文件并检查录像占用空间
    checkRecordSpace: function (directory, maxSpace) {
        const size = this.calculateTotalSpace(directory);
        return size>maxSpace;
    },
    /**
     * 如果当前目录是空的，就删除目录
     * @param directory
     */
    deleteEmptyDirectory:function(directory){
        if (!fs.existsSync(directory)) {
            return;
        }
        const files = fs.readdirSync(directory);
        if (files.length === 0) {
            fs.rmdirSync(directory);
        }
    },
    // 删除目录
    deleteDirectory: function (directory) {
        // 跳过以.开头的目录，是 /mnt/record1/.Recycle_bin 目录的最后一层
         const array = directory.split('/');
        if (array[array.length-1].indexOf('.') === 0) {
            return;
        }
        if (fs.existsSync(directory)) {
            // 先判断有没有读写权限，如果没有读写权限则跳过
            try {
                fs.accessSync(directory, fs.constants.R_OK | fs.constants.W_OK);

                fs.readdirSync(directory).forEach((file) => {
                    const filePath = path.join(directory, file);

                    if (fs.lstatSync(filePath).isDirectory()) {
                        // 递归删除子目录
                        this.deleteDirectory(filePath);
                    } else {
                        // 删除文件
                        console.info(TAG, "删除文件", filePath);
                        fs.unlinkSync(filePath);
                    }
                });

                // 删除空目录
                fs.rmdirSync(directory);
            }catch (e){
                console.info(TAG, "没有权限，跳过", directory);
            }
        }
    },
    // 遍历获取所有的文件，并排序
    getAllFiles:function(directory){
        let ret = [];
        try {
            // 获取目录下所有文件和子目录
            let files = fs.readdirSync(directory);
            // 遍历文件和子目录
            for (let i = 0; i < files.length; i++) {
                const filePath = path.join(directory, files[i]);
                // 获取文件信息
                const stat = fs.statSync(filePath);
                if (stat.isFile()) {
                    // 如果是文件，累加文件大小
                    ret.push({
                        name:files[i],
                        createTime:stat.birthtimeMs,
                        path : filePath,
                        type: 'file',
                        size:stat.size
                    });
                } else if (stat.isDirectory()) {
                    // 如果是子目录，递归调用 calculateTotalSpace
                    ret.push({
                        name:files[i],
                        createTime:stat.birthtimeMs,
                        path : filePath,
                        type: 'directory'
                    });
                    ret = ret.concat(this.getAllFiles(filePath));
                }
            }
        } catch (e) {
            console.error(TAG, "遍历文件出现错误", directory, e);
        }
        ret.sort(function (a, b) {
            return a.time - b.time;
        });
        return ret;
    },
    clearRecordSpace: function (directory) {
        let files = this.getAllFiles(directory);

        // 总空间占用大小
        let totalSize = 0;
        files.forEach((file) => {
            if (file.type === 'file') {
                totalSize += file.size;
            }
        });
        console.info(files);
        let sizeSum = totalSize;
        // 遍历文件，删除最早的文件，直到空间足够
        for (let i = 0; i < files.length; i++) {
            const file = files[i];
            // 如果是文件，累加文件大小
            if (file.type === 'file') {
                // 如果是文件，累加文件大小
                const size = file.size;

                // 删除文件
                fs.unlinkSync(file.path);
                sizeSum -= size;
                console.info(TAG, "删除文件", file.path, "剩余占用空间", sizeSum, 'compare', config.record.maxSpace);
                if (sizeSum < config.record.maxSpace) {
                    break;
                }
            } else if (file.type === 'directory') {
                this.deleteEmptyDirectory(file.path);
            }
        }
    },
    /**
     *
     * @param deviceId
     * @param channelId
     * @param startTime moment.js 对象
     * @param endTime moment.js 对象
     */
    getFileList: function (deviceId, channelId, startTime, endTime) {
        const path = config.record.path;
        let files = [];
        // 遍历天
        for(let day = startTime; day.isBefore(endTime); day.add(1, 'days')){
            const directory = `${path}/${day.format('YYYY')}/${day.format('MM')}/${day.format('DD')}`;
            const channelPath = `${directory}/${deviceId}/${channelId}`;
            console.info(TAG, "遍历目录", channelPath);
            // 读取目录下所有文件
            const fileList = fs.readdirSync(channelPath);
            // 遍历文件
            for(let i=0;i<fileList.length;i++){
                const file = fileList[i];
                const stat = fs.statSync(`${channelPath}/${file}`);
                if(stat.isFile()){
                    const fileName = file.replace(".mkv", "");
                    if(fileName.indexOf('_')>0){
                        const array = fileName.split('_');
                        const startInFile = array[0];
                        const endInFile = array[1];
                        const startInFileMoment = moment(startInFile, "YYYYMMDD-HHmmss");
                        const endInFileMoment = moment(endInFile, "YYYYMMDD-HHmmss");
                        if(startInFileMoment.isBetween(startTime, endTime) || endInFileMoment.isBetween(startTime, endTime)){
                            files.push({
                                path:`${channelPath.replace(path, '')}/${file}`,
                                fileSize: stat.size,
                                startTime: startInFileMoment.format("YYYY-MM-DD HH:mm:ss"),
                                endTime: endInFileMoment.format("YYYY-MM-DD HH:mm:ss"),
                                duration : endInFileMoment.diff(startInFileMoment, 'seconds')
                            });
                        }
                    }
                }
            }
        }
        return files;
    }
};

module.exports = directoryUtils;
